from zope.interface import implements

from twisted.plugin import getPlugins
from twisted.internet import reactor

from toneedu.interfaces import ITonePlugin, IController
from toneedu.exceptions import NoSuchPluginError
from toneedu.decorators import pluginRequired
from toneedu.midi import midi
from toneedu import plugins

class Controller:
    implements(IController)
    
    def __init__(self):
        self._plugin = None
        self._pluginList = None
        self._enumeratePlugins()

    def getPlugins(self):
        response = {}
        for name, plugin in self._pluginList.items():
            response[name] = plugin.description
        return response

    def selectPlugin(self, pluginName):
        for name, plugin in self._pluginList.items():
            if name.lower() == pluginName.lower():
                self._plugin = plugin
                return pluginName
            else:
                raise NoSuchPluginError(pluginName)
    
    @pluginRequired
    def getQuestion(self):
        return self._plugin.getQuestion()

    @pluginRequired
    def getAnswer(self):
        return self._plugin.getAnswer()
    
    @pluginRequired
    def answerList(self):
        return self._plugin.getAnswers()
    
    @pluginRequired
    def optionList(self):
        return self._plugin.getOptions()

    @pluginRequired
    def pluginHelp(self):
        return self._plugin.getHelp()
    
    @pluginRequired
    def tryAgain(self):
        return self._plugin.tryAgain()

    @pluginRequired
    def setOption(self, key, value):
        return self._plugin.setOption(key, value)

    @pluginRequired
    def checkAnswer(self, answer):
        return self._plugin.checkAnswer(answer)

    def isPluginSelected(self):
        return not self._plugin == None

    def getSoundDevices(self):
        return midi.getOutputDevices()

    def initSoundDevice(self, devnum):
        return midi.initDevice(devnum)

    def exit(self):
        midi.terminate()
        reactor.stop()
    
    def _enumeratePlugins(self):
        self._pluginList = {}

        for plugin in getPlugins(ITonePlugin, plugins):
            self._pluginList[plugin.name] = plugin
        

controller = Controller()
